<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DBC解析器全面兼容性测试</title>
    <style>
        body { 
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1400px; 
            margin: 0 auto; 
            padding: 20px; 
            background: #f7f7f7;
            min-height: 100vh;
        }
        .container {
            background: rgba(255, 255, 255, 0.95);
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
        }
        h1 { 
            color: #333; 
            text-align: center; 
            margin-bottom: 30px;
            font-size: 2.2em;
        }
        .stats { 
            background: #f8f9fa;
            padding: 20px; 
            border-radius: 10px; 
            margin: 20px 0;
            text-align: center;
            border-left: 5px solid #007bff;
        }
        .result { 
            margin: 8px 0; 
            padding: 10px; 
            border-radius: 8px; 
            display: flex;
            align-items: center;
            transition: all 0.3s ease;
            font-size: 0.85em;
        }
        .result:hover {
            transform: translateX(5px);
        }
        .success { 
            background: linear-gradient(135deg, #d4edda, #c3e6cb); 
            border-left: 5px solid #28a745;
        }
        .error { 
            background: linear-gradient(135deg, #f8d7da, #f5c6cb); 
            border-left: 5px solid #dc3545;
        }
        .icon {
            font-size: 1.1em;
            margin-right: 10px;
        }
        .success .icon { color: #28a745; }
        .error .icon { color: #dc3545; }
        .filename { 
            font-weight: bold; 
            font-size: 0.9em;
            margin-right: 15px;
            min-width: 180px;
        }
        .details { 
            color: #666; 
            font-size: 0.8em;
            flex-grow: 1;
        }
        .error-msg { 
            color: #721c24; 
            font-weight: 500;
        }
        .test-controls {
            text-align: center;
            margin: 20px 0;
        }
        button {
            background: linear-gradient(135deg, #007bff, #0056b3);
            color: white;
            border: none;
            padding: 12px 30px;
            border-radius: 25px;
            cursor: pointer;
            font-size: 1.1em;
            transition: all 0.3s ease;
            margin: 0 10px;
        }
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,123,255,0.3);
        }
        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
            transform: none;
        }
        .progress {
            width: 100%;
            height: 20px;
            background: #e9ecef;
            border-radius: 10px;
            overflow: hidden;
            margin: 20px 0;
        }
        .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, #007bff, #28a745);
            width: 0%;
            transition: width 0.3s ease;
        }
        .results-container {
            max-height: 600px;
            overflow-y: auto;
            border: 1px solid #dee2e6;
            border-radius: 8px;
            padding: 10px;
            background: #f8f9fa;
        }
        .summary {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin: 20px 0;
        }
        .summary-item {
            background: white;
            padding: 15px;
            border-radius: 8px;
            text-align: center;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        .summary-number {
            font-size: 2em;
            font-weight: bold;
            margin-bottom: 5px;
        }
        .success-rate { color: #28a745; }
        .total-files { color: #007bff; }
        .failed-files { color: #dc3545; }
        .avg-time { color: #ffc107; }
        .theme-selector {
            position: fixed;
            top: 20px;
            right: 20px;
            display: flex;
            align-items: center;
            gap: 10px;
            background: white;
            padding: 10px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 1000;
            border: 1px solid #ddd;
        }
        .theme-selector label {
            font-weight: bold;
            color: #333;
        }
        .theme-selector select {
            padding: 8px 12px;
            border-radius: 5px;
            border: 1px solid #007bff;
            background: white;
            font-size: 0.9em;
            cursor: pointer;
            min-width: 150px;
        }
        .theme-selector select:hover {
            border-color: #0056b3;
        }
        .color-guide {
            position: fixed;
            top: 20px;
            left: 20px;
            max-width: 300px;
            background: white;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            z-index: 999;
            border: 1px solid #ddd;
            display: none;
        }
        .color-guide.show {
            display: block;
        }
        .color-guide h4 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 1.1em;
        }
        .color-guide .guide-item {
            margin-bottom: 8px;
            padding: 5px;
            border-left: 3px solid #007bff;
            background: #f8f9fa;
            font-size: 0.85em;
        }
        .guide-toggle {
            position: fixed;
            top: 80px;
            right: 20px;
            background: #007bff;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 0.9em;
            z-index: 1000;
        }
        .guide-toggle:hover {
            background: #0056b3;
        }
    </style>
</head>
<body>
    <div class="theme-selector">
        <label for="bgColorSelect">背景颜色:</label>
        <select id="bgColorSelect" onchange="changeBackgroundColor(this.value)">
            <option value="#f7f7f7">淡暖灰色</option>
            <option value="#f5f5f5">浅灰色</option>
            <option value="#e6f2ff">淡蓝色</option>
            <option value="#f9f4e8">奶油色</option>
            <option value="#e8f5e9">淡绿色</option>
            <option value="#e0f7fa">淡薄荷色</option>
            <option value="#ffffff">纯白色</option>
            <option value="linear-gradient(135deg, #ffffff 0%, #f0f0f0 100%)">灰白渐变</option>
            
            <optgroup label="护眼系列">
                <option value="#e8f4e8">翠绿护眼</option>
                <option value="#f0f8e8">自然绿</option>
                <option value="#e8f0e8">森林绿</option>
            </optgroup>
            
            <optgroup label="深色模式">
                <option value="#1a1a1a">经典黑夜</option>
                <option value="#2d2d30">深灰夜间</option>
                <option value="#0d1117">GitHub暗色</option>
                <option value="#1e1e2e">优雅深紫</option>
            </optgroup>
            
            <optgroup label="现代渐变">
                <option value="linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)">珊瑚粉渐变</option>
                <option value="linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)">薄荷粉渐变</option>
                <option value="linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)">暖橙渐变</option>
                <option value="linear-gradient(135deg, #e0c3fc 0%, #9bb5ff 100%)">薰衣草渐变</option>
                <option value="linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)">青柠渐变</option>
                <option value="linear-gradient(135deg, #fa709a 0%, #fee140 100%)">活力渐变</option>
            </optgroup>
            
            <optgroup label="专业色调">
                <option value="#f8f9fa">极简白</option>
                <option value="#343a40">专业深灰</option>
                <option value="#495057">商务灰</option>
                <option value="#6c757d">中性灰</option>
            </optgroup>
            
            <optgroup label="原始色彩">
                <option value="linear-gradient(135deg, #667eea 0%, #764ba2 100%)">蓝紫色渐变</option>
            </optgroup>
        </select>
    </div>
    
    <button class="guide-toggle" onclick="toggleColorGuide()">颜色说明</button>
    
    <div class="color-guide" id="colorGuide">
        <h4>🎨 背景颜色使用指南</h4>
        
        <div class="guide-item">
            <strong>护眼系列</strong><br>
            • 翠绿护眼：长时间阅读，减少眼疲劳<br>
            • 自然绿：户外工作环境，自然舒适<br>
            • 森林绿：需要专注思考的工作场景
        </div>
        
        <div class="guide-item">
            <strong>深色模式</strong><br>
            • 经典黑夜：夜间工作，减少蓝光刺激<br>
            • 深灰夜间：长时间编程开发<br>
            • GitHub暗色：代码审查，技术专业<br>
            • 优雅深紫：创意设计，高端专业
        </div>
        
        <div class="guide-item">
            <strong>现代渐变</strong><br>
            • 珊瑚粉：温暖友好，适合展示场景<br>
            • 薄荷粉：清新优雅，适合设计工作<br>
            • 暖橙：活力温馨，适合团队协作<br>
            • 薰衣草：放松舒缓，适合长时间使用<br>
            • 青柠：清新活力，适合创新项目<br>
            • 活力：充满动感，适合快节奏工作
        </div>
        
        <div class="guide-item">
            <strong>专业色调</strong><br>
            • 极简白：正式场合，商务演示<br>
            • 专业深灰：企业级应用，严肃工作<br>
            • 商务灰：办公环境，专业稳重<br>
            • 中性灰：多人协作，中性平衡
        </div>
    </div>
    
    <div class="container">
        <h1>🚗 DBC解析器全面兼容性测试</h1>
        
        <div class="test-controls">
            <button onclick="runAllTests()" id="testBtn">测试所有DBC文件 (55个)</button>
            <button onclick="runQuickTest()" id="quickBtn">快速测试 (核心9个)</button>
        </div>
        
        <div class="progress">
            <div class="progress-bar" id="progressBar"></div>
        </div>
        
        <div class="stats" id="stats">
            <h3>测试统计</h3>
            <div id="statsContent">选择测试模式开始测试</div>
        </div>
        
        <div class="summary" id="summary" style="display: none;">
            <div class="summary-item">
                <div class="summary-number success-rate" id="successRate">0%</div>
                <div>成功率</div>
            </div>
            <div class="summary-item">
                <div class="summary-number total-files" id="totalFiles">0</div>
                <div>总文件数</div>
            </div>
            <div class="summary-item">
                <div class="summary-number failed-files" id="failedFiles">0</div>
                <div>失败文件</div>
            </div>
            <div class="summary-item">
                <div class="summary-number avg-time" id="avgTime">0ms</div>
                <div>平均解析时间</div>
            </div>
        </div>
        
        <div class="results-container">
            <div id="results"></div>
        </div>
    </div>

    <script src="dbc-parser.js"></script>
    <script>
        // 背景颜色切换函数
        function changeBackgroundColor(color) {
            document.body.style.background = color;
            
            // 深色模式文字颜色调整
            const isDarkMode = color.includes('#1a1a1a') || color.includes('#2d2d30') || 
                              color.includes('#0d1117') || color.includes('#1e1e2e') ||
                              color.includes('#343a40') || color.includes('#495057') || 
                              color.includes('#6c757d');
            
            if (isDarkMode) {
                document.body.style.color = '#ffffff';
                document.querySelector('.container').style.background = 'rgba(255, 255, 255, 0.1)';
                document.querySelector('.container').style.color = '#ffffff';
            } else {
                document.body.style.color = '';
                document.querySelector('.container').style.background = 'rgba(255, 255, 255, 0.95)';
                document.querySelector('.container').style.color = '';
            }
            
            // 保存用户的颜色偏好到localStorage
            localStorage.setItem('preferredBackgroundColor', color);
        }
        
        // 切换颜色说明面板
        function toggleColorGuide() {
            const guide = document.getElementById('colorGuide');
            guide.classList.toggle('show');
        }
        
        // 页面加载时，检查是否有保存的颜色偏好
        window.addEventListener('DOMContentLoaded', function() {
            const savedColor = localStorage.getItem('preferredBackgroundColor');
            if (savedColor) {
                document.body.style.background = savedColor;
                
                // 更新下拉菜单选中值
                const select = document.getElementById('bgColorSelect');
                for (let i = 0; i < select.options.length; i++) {
                    if (select.options[i].value === savedColor) {
                        select.selectedIndex = i;
                        break;
                    }
                }
            }
        });
        
        // 所有DBC文件列表 (根据实际存在的文件)
        const allFiles = [
            'acura_ilx_2016_nidec.dbc',
            'bmw_e9x_e8x.dbc',
            'cadillac_ct6_chassis.dbc',
            'cadillac_ct6_object.dbc',
            'cadillac_ct6_powertrain.dbc',
            'chrysler_cusw.dbc',
            'chrysler_pacifica_2017_hybrid_private_fusion.dbc',
            'comma_body.dbc',
            'ESR.dbc',
            'fca_giorgio.dbc',
            'FORD_CADS_64.dbc',
            'FORD_CADS.dbc',
            'ford_cgea1_2_bodycan_2011.dbc',
            'ford_cgea1_2_ptcan_2011.dbc',
            'ford_fusion_2018_adas.dbc',
            'ford_fusion_2018_pt.dbc',
            'ford_lincoln_base_pt.dbc',
            'gm_global_a_chassis.dbc',
            'gm_global_a_high_voltage_management.dbc',
            'gm_global_a_lowspeed_1818125.dbc',
            'gm_global_a_lowspeed.dbc',
            'gm_global_a_object.dbc',
            'gm_global_a_powertrain_expansion.dbc',
            'gwm_haval_h6_phev_2024.dbc',
            'hongqi_hs5.dbc',
            'hyundai_2015_ccan.dbc',
            'hyundai_2015_mcan.dbc',
            'hyundai_i30_2014.dbc',
            'hyundai_kia_generic.dbc',
            'hyundai_santafe_2007.dbc',
            'luxgen_s5_2015.dbc',
            'mazda_2017.dbc',
            'mazda_3_2019.dbc',
            'mazda_radar.dbc',
            'mazda_rx8.dbc',
            'mercedes_benz_e350_2010.dbc',
            'nissan_xterra_2011.dbc',
            'opel_omega_2001.dbc',
            'rivian_park_assist_can.dbc',
            'rivian_primary_actuator.dbc',
            'tesla_can.dbc',
            'tesla_model3_party.dbc',
            'tesla_model3_vehicle.dbc',
            'tesla_powertrain.dbc',
            'toyota_2017_ref_pt.dbc',
            'toyota_adas.dbc',
            'toyota_iQ_2009_can.dbc',
            'toyota_prius_2010_pt.dbc',
            'toyota_radar_dsu_tssp.dbc',
            'toyota_tss2_adas.dbc',
            'volvo_v40_2017_pt.dbc',
            'volvo_v60_2015_pt.dbc',
            'vw_meb.dbc',
            'vw_mqb.dbc',
            'vw_mqbevo.dbc',
            'vw_pq.dbc'
        ];
        
        // 核心测试文件列表
        const coreFiles = [
            'acura_ilx_2016_nidec.dbc',
            'bmw_e9x_e8x.dbc', 
            'cadillac_ct6_chassis.dbc',
            'cadillac_ct6_object.dbc',
            'ford_lincoln_base_pt.dbc',
            'tesla_model3_vehicle.dbc',
            'mazda_2017.dbc',
            'toyota_2017_ref_pt.dbc',
            'ESR.dbc'
        ];

        async function testFile(filename) {
            const dbcPath = `./${filename}`;
            
            try {
                const response = await fetch(dbcPath);
                if (!response.ok) {
                    throw new Error(`Failed to fetch ${filename}: ${response.status}`);
                }
                
                const content = await response.text();
                const startTime = performance.now();
                
                const tokenizer = new DBCTokenizer(content);
                const parser = new DBCParser(tokenizer);
                const result = parser.parse();
                
                const endTime = performance.now();
                const parseTime = Math.round(endTime - startTime);
                
                return {
                    success: true,
                    filename: filename,
                    parseTime: parseTime,
                    frameCount: result.frames ? result.frames.length : 0,
                    signalCount: result.frames ? result.frames.reduce((sum, frame) => sum + (frame.signals ? frame.signals.length : 0), 0) : 0,
                    warnings: result.warnings ? result.warnings.length : 0
                };
            } catch (error) {
                return {
                    success: false,
                    filename: filename,
                    error: error.message
                };
            }
        }

        async function runTests(fileList, testName) {
            const button = document.getElementById('testBtn');
            const quickBtn = document.getElementById('quickBtn');
            const results = document.getElementById('results');
            const stats = document.getElementById('statsContent');
            const progressBar = document.getElementById('progressBar');
            const summary = document.getElementById('summary');
            
            button.disabled = true;
            quickBtn.disabled = true;
            button.textContent = '测试中...';
            quickBtn.textContent = '测试中...';
            results.innerHTML = '';
            summary.style.display = 'none';
            
            let successCount = 0;
            let totalCount = fileList.length;
            let totalTime = 0;
            let totalFrames = 0;
            let totalSignals = 0;
            
            for (let i = 0; i < fileList.length; i++) {
                const filename = fileList[i];
                
                // 更新进度条
                const progress = ((i + 1) / totalCount) * 100;
                progressBar.style.width = `${progress}%`;
                
                // 显示当前测试文件
                stats.innerHTML = `<h3>${testName}</h3><div>正在测试: ${filename} (${i + 1}/${totalCount})</div>`;
                
                const result = await testFile(filename);
                
                if (result.success) {
                    successCount++;
                    totalTime += result.parseTime;
                    totalFrames += result.frameCount;
                    totalSignals += result.signalCount;
                    
                    results.innerHTML += `
                        <div class="result success">
                            <span class="icon">✅</span>
                            <span class="filename">${result.filename}</span>
                            <span class="details">${result.parseTime}ms | ${result.frameCount}帧 | ${result.signalCount}信号 | ${result.warnings}警告</span>
                        </div>
                    `;
                } else {
                    results.innerHTML += `
                        <div class="result error">
                            <span class="icon">❌</span>
                            <span class="filename">${result.filename}</span>
                            <span class="details error-msg">错误: ${result.error.substring(0, 80)}${result.error.length > 80 ? '...' : ''}</span>
                        </div>
                    `;
                }
                
                // 实时更新进度统计
                const currentSuccess = successCount;
                const currentTotal = i + 1;
                const currentRate = Math.round((currentSuccess / currentTotal) * 100);
                
                stats.innerHTML = `
                    <h3>${testName}</h3>
                    <div><strong>成功率: ${currentRate}% (${currentSuccess}/${currentTotal})</strong></div>
                    <div>进度: ${currentTotal}/${totalCount}</div>
                `;
            }
            
            // 计算统计数据
            const successRate = Math.round((successCount / totalCount) * 100);
            const avgTime = successCount > 0 ? Math.round(totalTime / successCount) : 0;
            
            // 显示摘要统计
            document.getElementById('successRate').textContent = `${successRate}%`;
            document.getElementById('totalFiles').textContent = totalCount;
            document.getElementById('failedFiles').textContent = totalCount - successCount;
            document.getElementById('avgTime').textContent = `${avgTime}ms`;
            summary.style.display = 'grid';
            
            // 最终统计
            stats.innerHTML = `
                <h3>${testName} - 完成</h3>
                <div><strong>最终成功率: ${successRate}% (${successCount}/${totalCount})</strong></div>
                <div>总帧数: ${totalFrames} | 总信号数: ${totalSignals}</div>
                <div>平均解析时间: ${avgTime}ms</div>
                <div style="color: #28a745;">✅ 成功: ${successCount} 个</div>
                <div style="color: #dc3545;">❌ 失败: ${totalCount - successCount} 个</div>
            `;
            
            button.disabled = false;
            quickBtn.disabled = false;
            button.textContent = '测试所有DBC文件 (55个)';
            quickBtn.textContent = '快速测试 (核心9个)';
            progressBar.style.width = '100%';
        }
        
        async function runAllTests() {
            await runTests(allFiles, '全面兼容性测试 (55个文件)');
        }
        
        async function runQuickTest() {
            await runTests(coreFiles, '核心文件测试 (9个文件)');
        }
    </script>
</body>
</html>